﻿using System;
using System.Collections.Generic;
using System.Linq;
using Pixels.Rendering;
using Pixels.Logic;

using Sargon;
using Ur;

namespace Pixels.Interface
{
    public class Interface : Sargon.State
    {
        static public Interface Instance { get; private set;}
        public Interface() {

            Instance = this;
            myCanvas = new Canvas(300f);
            myCanvas.doSort = true;

            register_method(Sargon.Trigger.tick, tick);
            register_method(Sargon.Trigger.frame, frame);
            register_method(Sargon.Trigger.pre_frame, input);            

            turnLogWindow = new Window("Window", 50, 50, 800, 700);            
            var btn = new Button("", 800 - 60, 0, 60, 60);            
            btn.attachToParent(turnLogWindow);
            btn.Click += delegate { 
                turnLogWindow.hide(); 
            };

            btn.color = new Color(0, 0, 0, 0);
            btn.label = "";

            var endturnButton = new Button("", Screen.w - 223 - 0, Screen.h - 61 - 0, 223, 61);
            endturnButton.zed = 400;
            endturnButton.Click += delegate {
                World.Logic.commenceTurnEnd();                
            };

            endturnButton.textureID = "end_turn_btn";

            turnLogWindow.hide();

            technologyWindow = new TechWindow("Technologies", 20, 20, 800, 700);            

            int y = 60;
            for (Technologies t = 0; t < Technologies.ubound; t++) {
                if (t == Technologies.none) continue;
                var tb = new TechButton(t, 4, y, 792, 40);
                y += 70;
                tb.attachToParent(technologyWindow);
                tb.Click += delegate {
                    if (tb.techID.Allowed() && !tb.techID.Researched()) World.CurrentResearch = tb.techID;
                };
            }

            var closeButton = new Button("", 800 - 70, 0, 60, 60);
            closeButton.attachToParent(technologyWindow);
            closeButton.Click += delegate {
                technologyWindow.hide();
            };
            closeButton.color = new Color(0, 0, 0, 0f);
            closeButton.label = "";

            technologyWindow.hide();

            var openTechs = new Button("", Screen.w - 182, Screen.h - 61 - 16 - 39, 170, 39);
            openTechs.Click += delegate {
                technologyWindow.show();
            };

            Audio.play("music1");

            openTechs.textureID = "open_tech_btn";

            createMessage("Are you alive, Captain? We have crashlanded on Persephone Prime! This planet is notorious for its nocturnal predators! We must scavenge what we can and get off this rock as soon as possible");


            //discoverWindow = new Window("Window", 50, 50, 600, 500);
            //var discoverCloseBtn = new Button("[x]", 600 - 40, 8, 32, 32);
            //discoverCloseBtn.attachToParent(discoverWindow);
            //discoverCloseBtn.Click += delegate
            //{
            //    discoverWindow.hide();
            //};
            //discoverWindow.hide();

            buildWindow = new Window("Window", 50, 50, 600, 500);
            
            buildWindow.hide();

            var b1 = new SideButton(Screen.w - 79, 200, 79, 81, "symbol_cloud");

            b1.tooltip = new Tooltip("Weather Baloon", "Get weather forecast for tomorrow");


            var b2 = new SideButton(Screen.w - 79, 280, 79, 81, "symbol_freeze");

            var unfreezeCost = GlobalConsts.unfreezeCost;

            b2.Click += delegate {
                //createMessage("We have activated a distress beacon! Help is on the way! Congratulations, we are finally getting off this rock!", true);//DEBUG - FFFUUUUUUU
                if (World.Colony.accumulatedResources.hasEnough(unfreezeCost)) { 
                    World.Logic.unfreezePerson();
                    World.Colony.accumulatedResources.subtractCost(unfreezeCost);
                }                
            };

            b2.tooltip = new Tooltip("Cryogenic override", "Forcibly bring a colonist out of criogenic sleep.");
            b2.tooltip.addSymbols(unfreezeCost);

            var b3 = new SideButton(Screen.w - 79, 360, 79, 81, "symbol_radio");
            b3.tooltip = new Tooltip("Activate Distress Signal", "Maybe someone will hear our call");
            b3.tooltip.addSymbols(GlobalConsts.radioCost);

            b3.Click += delegate {
                createMessage("We have activated a distress beacon! Help is on the way! Congratulations, we are finally getting off this rock!", true);
            };

            WeatherButton = b1;
            UnfreezeButton = b2;
            DistressButton = b3;
            

        }

        public Window turnLogWindow;
        public Window technologyWindow;
        public Window discoverWindow;
        public Window buildWindow;
        
        public Canvas myCanvas;

        List<InterfaceElement> elements = new List<InterfaceElement>();

        /// <summary> You do not call this. InterfaceElement calls this </summary>        
        internal void elementAdded(InterfaceElement element) {
            elements.Add(element);
        }

        /// <summary> You do not call this. InterfaceElement calls this </summary>        
        internal void elementRemoved(InterfaceElement element) {
            elements.Remove(element);
        }

        public Button UnfreezeButton;
        public Button WeatherButton;
        public Button DistressButton;

        void tick() {
            foreach (var element in elements) element.tick();
            UnfreezeButton.visible = true;
            WeatherButton.visible = Technologies.weather_patterns.Researched();
            DistressButton.visible = World.RadarBuilt;
        }

        void frame() {
            Render.canvas = this.myCanvas;
            renderInterfaceOverlay();
            foreach (var el in elements) el.render();
            renderTooltip();
        }

        void input() {
            var state = Input.state;
            hilitElement = null; resolveHilite();
            if (hilitElement != null) tooltip = hilitElement.tooltip;
            foreach (var el in elements.ToArray()) el.input(state);
            
            if (Keys.Space.pressed()) World.Logic.commenceTurnEnd();            
        }

        public InterfaceElement hilitElement;
        void resolveHilite() {
            try {
                foreach (var el in elements) if (el.Visible && el.respondsToHilite && el.ScreenRect.contains(Mouse.coords)) hilitElement = el;
            } catch {

            }
        }

        void renderInterfaceOverlay() {
            var s0 = Render.spriteInBox("overlay_up", new Rect(0, 0, 1280, 70), true);
            var s1 = Render.spriteInBox("overlay_left", new Rect(0, 70, 37, 564), true);
            var s2 = Render.spriteInBox("overlay_right", new Rect(1280-34, 70, 34, 564), true);
            var s3 = Render.spriteInBox("overlay_down", new Rect(0, Screen.h-86, 1280, 86), true);

            Render.symbolZ = 300;
            Render.Symbol(new crds2(30,  30),  GlobalConsts.getResourceConsts(Resource.Apples).icon, World.Colony.accumulatedResources[Resource.Apples]);
            Render.Symbol(new crds2(100,  30), GlobalConsts.getResourceConsts( Resource.Cogs).icon, World.Colony.accumulatedResources[Resource.Cogs]);
            Render.Symbol(new crds2(170, 30),  GlobalConsts.getResourceConsts( Resource.Power).icon, World.Colony.accumulatedResources[Resource.Power]);
            Render.Symbol(new crds2(240, 30),  GlobalConsts.getResourceConsts( Resource.Special).icon, World.Colony.accumulatedResources[Resource.Special]);
            Render.Symbol(new crds2(310, 30),  "icon_bulb", World.Colony.totalResearch );
            Render.Symbol(new crds2(380, 30), "icon_shield", World.Colony.totalDefense);
        }

        void renderTooltip() {
            var txt = Render.textInBox(tooltip.largeText, new Rect(500, 20, 600, 80),true);
            txt.verticalAlign = Text.VAlign.top;         

            var txt2 = Render.textInBox(tooltip.smallText, new Rect(500, 49, 600, 80),true);
            txt2.verticalAlign = Text.VAlign.top;         
            txt2.characterSize = 16;

            var sc = new crds2(530, 60);
            foreach (var symbol in tooltip.symbols) { 
                Render.Symbol(sc, symbol.iconID, symbol.amount, symbol.delta);
                sc = sc + new crds2(60, 0);
            }

        }

        static public Window createMessage(string messageString, bool isTerminal = false) {
            var w = new Window("", 0, 0, 800, 700);            

            var msg = new Label(messageString, 30, 30, 800 - 60, 700 - 60);            
            msg.verticalAlign = Text.VAlign.middle;
            msg.horizontalAlign = Text.HAlign.center;
            msg.attachToParent(w);            

            var closeBtn = new Button("", 800 - 60, 0, 60, 60);
            closeBtn.color = new Color(1, 1, 1, 0);
            closeBtn.attachToParent(w);
            closeBtn.Click += delegate {
                w.die();
                if (isTerminal) Sargon.Game.terminate();
            };
            
            
            return w;
        }


        static public Tooltip tooltip = new Tooltip("", "");

    }

    public class Tooltip
    {
        public string largeText;
        public string smallText;        
        public List<Symbol> symbols;
        public Tooltip(string largeText, string auxText) {
            this.largeText = largeText;
            this.smallText = auxText;
            this.symbols = new List<Symbol>();
        }

        public void addSymbols(ResourcePool pool) {
            for (Resource r = 0; r < Resource.Max; r++) {
                if (pool[r] > 0) {
                    var c = GlobalConsts.getResourceConsts(r);
                    symbols.Add(new Symbol(c.icon, pool[r]));
                }
            }
        }



        public class Symbol
        {
            public string iconID;
            public int amount;
            public int delta;

            public Symbol(string iconID, int amount, int delta = 0) {
                this.iconID = iconID;
                this.amount = amount;
                this.delta  = delta;
            }
        }

    }
}
